package com.california.pay.common.concurrent;

/**
 * 锁模板
 */
public abstract class LockTemplate {
    /**
     * 加锁下执行操作
     *
     * @param key       锁关键字
     * @param waitTime  等待锁时间
     * @param leaseTime 锁释放时间
     * @param callback  回调
     * @param <T>
     * @return
     */
    public abstract <T> T execute(String key, long waitTime, long leaseTime, LockCallback<T> callback);

    /**
     * 加锁下执行操作
     *
     * @param key      锁关键字
     * @param waitTime 等待锁时间
     * @param callback 回调
     * @param <T>
     * @return
     */
    public <T> T execute(String key, long waitTime, LockCallback<T> callback) {
        return execute(key, waitTime, -1, callback);
    }

    /**
     * 加锁下执行操作
     *
     * @param key      锁关键字
     * @param callback 回调
     * @param <T>
     * @return
     */
    public <T> T execute(String key, LockCallback<T> callback) {
        return execute(key, -1, -1, callback);
    }

    /**
     * 加锁下执行操作
     *
     * @param key       锁关键字
     * @param waitTime  等待锁时间
     * @param leaseTime 锁释放时间
     * @param callback  回调
     * @return
     */
    public void executeWithoutResult(String key, long waitTime, long leaseTime, ILockCallbackWithoutResult callback) {
        execute(key, waitTime, leaseTime, locked->{
            callback.doWithLock(locked);
            return null;
        });
    }

    /**
     * 加锁下执行操作
     *
     * @param key       锁关键字
     * @param waitTime  等待锁时间
     * @param callback  回调
     * @return
     */
    public void executeWithoutResult(String key, long waitTime, ILockCallbackWithoutResult callback) {
        executeWithoutResult(key, waitTime, -1, callback);
    }

    /**
     * 加锁下执行操作
     *
     * @param key       锁关键字
     * @param callback  回调
     * @return
     */
    public void executeWithoutResult(String key, ILockCallbackWithoutResult callback) {
        executeWithoutResult(key,-1,  -1, callback);
    }
}
